#pragma once
#include "Common.h"
#include "ThreadCache.h"
#include "PageCache.h"

void* ConcurrentAlloc(size_t size)
{
    if (size > max_byte)
    {
        size_t alignedSize = Tool::RoundUp(size);
        size_t k = alignedSize >> page_shift;

        PageCache::GetInstance()->GetMtx().lock();
        Span* span = PageCache::GetInstance()->NewSpan(k);
        PageCache::GetInstance()->GetMtx().unlock();

        return (void*)(span->_id << page_shift);
    }
    else {
        if (tls_threadcache == nullptr)
        {
            tls_threadcache = new ThreadCache;
        }
        return tls_threadcache->Allocate(size);
    }
}

void ConcurrentFree(void* ptr)
{
    assert(ptr);
    Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
    size_t size = span->_objSize;
    if (size > max_byte)
    {
        PageCache::GetInstance()->GetMtx().lock();
        PageCache::GetInstance()->ReleaseSpanToPageCache(span);
        PageCache::GetInstance()->GetMtx().unlock();
    }
    else
    {
        tls_threadcache->Deallocate(ptr, size);
    }
}